-module(counter).
-behaviour(gen_event).

-export([init/1, handle_event/2, handle_call/2, handle_info/2, code_change/3, terminate/2]).

-record
(
        state,
        {
                sequence = [],
                length = 0,
                smallest = 0,
                queue = priority_queue:new(),
                limit
        }
).

%% 
init(Limit) ->
        {
                ok,
                #state{limit = Limit}
        }.

handle_event({add_number, N}, State = #state{length = Length})
        when Length == 0 ->
                {
                        ok,
                        State#state
                        {
                                sequence = [N],
                                length = 1
                        }
                };
                

handle_event({add_number, N}, State = #state{sequence = [H | _T]})
        when N > H  ->
                EnlargedSeqence = [N, State#state.sequence],
                {
                        ok,
                        State#state
                        {
                                sequence = EnlargedSeqence,
                                length = State#state.length + 1
                        }
                };


handle_event({add_number, N}, State = #state{sequence = [H | _T], smallest = Smallest, length = Length})
        when N =< H, Length < Smallest ->
                {
                        ok,
                        State#state
                        {
                                sequence = [N],
                                length = 1
                        }
                };

handle_event({add_number, N}, State = #state{sequence = [H | _T]})
        when N =< H ->
                Sequence = State#state.sequence,
                EnlargedQueue = priority_queue:add(length(Sequence), Sequence, State#state.queue),
                EnlargedQeueSize = priority_queue:size(EnlargedQueue),
                NewQueue =
                        if
                                EnlargedQeueSize > State#state.limit ->
                                        priority_queue:remove_smallest(EnlargedQueue);
                                true ->
                                        EnlargedQueue
                        end,
                {
                        ok,
                        State#state
                        {
                                sequence = [N],
                                length = 1,
                                smallest = priority_queue:smallest(NewQueue),
                                queue = NewQueue
                        }
                };

%%
handle_event(_Event, Pid) ->
        {
                ok,
                Pid
        }.

%%
handle_call(get_data, S) ->
        io:format("get data~n"),
        {
                ok,
                [],
                S
        };

handle_call(_, State) ->
        {
                ok,
                ok,
                State
        }.

handle_info(_, State) ->
        {
                ok,
                State
        }.

code_change(_OldVsn, State, _Extra) ->
        {
                ok,
                State
        }.

terminate(_Reason, _State) ->
        ok.

